package cn.fl.ref.fnccappayeeinfobig.service.impl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;

import cmm.comm.facade.framework.api.ISysDictionaryApiService;
import cmm.mid.core.framework.dto.DataResultDTO;
import cmm.mid.core.framework.page.KeyValueVO;
import cmm.mid.core.framework.page.Pager;
import cn.cmm.base.framework.constant.BaseConstant;
import cn.cmm.base.framework.constant.BaseExceptionConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.base.framework.utils.CollectionUtils;
import cn.cmm.base.framework.utils.StringUtils;
import cn.cmm.cache.framework.utils.PropertiesCacheUtils;
import cn.fl.framework.base.context.CurrentThreadContext;
import cn.fl.ref.fnccappayeeinfobig.service.IFncCapPayeeInfoBigService;
import cn.fl.ref.fnccappayeeinfobig.transform.FncCapPayeeInfoBigVOTransform;
import cn.fl.ref.fnccappayeeinfobig.vo.FncCapPayeeInfoBigVO;
import cn.fl.ref.fncprjbscinfo.util.PayeeBigUtil;
import cn.fl.system.constant.SysLogConstant;
import fl.flow.facade.flow.api.IFlowApiService;
import fl.flow.facade.flow.dto.FlowStartParamsDTO;
import fl.ref.fnccappayeeinfobig.condition.FncCapPayeeInfoBigQueryCondition;
import fl.ref.fnccappayeeinfobig.constant.FncCapPayeeInfoBigConstant;
import fl.ref.fnccappayeeinfobig.dto.FncCapPayeeInfoBigDTO;
import fl.ref.fnccappayeeinfobig.service.IFncCapPayeeInfoBigApiService;

/**
 * @Description:业务层方法名称前缀：新增：add* 删除：remove* 修改：modify* 查询对象：select* get*
 *                                批量：batch* 查询集合：search* 服务实现层
 */
@Service
public class FncCapPayeeInfoBigServiceImpl implements IFncCapPayeeInfoBigService {

	private static final Logger logger = LoggerFactory.getLogger(IFncCapPayeeInfoBigService.class);
	//##发送私钥
	private static final String privateKey = "fncbigpay.fncbigpay.properties.paybig.privateKey";
	//##接受公钥
	//private static final String publicKey = "fncbigpay.fncbigpay.properties.paybig.publicKey";
	//##对接系统代码，用于标识唯一的对接系统 Y
	private static final String finCode ="fncbigpay.fncbigpay.properties.paybig.finCode"; 
	//##合作方代码，用于标识唯一的合作方
	private static final String orgCode ="fncbigpay.fncbigpay.properties.paybig.orgCode";
	//##服务代码，网银放款接口 
	private static final String seCode1="fncbigpay.fncbigpay.properties.paybig.seCode1";
	private static final String version1="fncbigpay.fncbigpay.properties.paybig.version1";
	//##服务代码 网银付款记录查询接口 
	private static final String seCode2="fncbigpay.fncbigpay.properties.paybig.seCode2"; 
	private static final String version2="fncbigpay.fncbigpay.properties.paybig.version2"; 
	//##签名密钥索引 
	private static final String signKeyIdx="fncbigpay.fncbigpay.properties.paybig.signKeyIdx";
	
	@Autowired
	private IFncCapPayeeInfoBigApiService fncCapPayeeInfoBigApiService;

	/**
	 * 字典服务层BEAN
	 */
	@Autowired
	private ISysDictionaryApiService sysDictionaryApiService;
	 /**
     * 流程服务
     */
    @Autowired
    private IFlowApiService flowApiService;
	@Override
	public FncCapPayeeInfoBigVO selectById(Long id) throws BaseException {
		if (StringUtils.isEmpty(id)) {
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,
					BaseExceptionConstant.BASE_EXCEPTION_CODE_600_NAME);
		}
		FncCapPayeeInfoBigDTO dto = this.fncCapPayeeInfoBigApiService.selectById(id);
		return FncCapPayeeInfoBigVOTransform.toVO(dto);
	}

	@Override
	public Long add(FncCapPayeeInfoBigVO entity) throws BaseException {
		if (null == entity) {
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,
					BaseExceptionConstant.BASE_EXCEPTION_CODE_600_NAME);
		}
		return this.fncCapPayeeInfoBigApiService.add(FncCapPayeeInfoBigVOTransform.toDTO(entity));
	}

	@Override
	public boolean modify(FncCapPayeeInfoBigVO entity) throws BaseException {
		if (null == entity) {
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,
					BaseExceptionConstant.BASE_EXCEPTION_CODE_600_NAME);
		}
		return this.fncCapPayeeInfoBigApiService.modify(FncCapPayeeInfoBigVOTransform.toDTO(entity));
	}

	@Override
	public Pager searchListPage(Pager page) throws BaseException {
		Pager pager = this.fncCapPayeeInfoBigApiService.searchListPage(page);

		// 设置显示内容
		if (pager != null) {
			List<FncCapPayeeInfoBigDTO> resultList = (List<FncCapPayeeInfoBigDTO>) pager.getResultList();
			if (CollectionUtils.isNotEmpty(resultList)) {

				// 付款类型(数据字典)列表
				List<KeyValueVO> payTypeList = sysDictionaryApiService.getKvList(
						FncCapPayeeInfoBigConstant.FNC_PAY_TYPE, CurrentThreadContext.getCurrentSysCd(),
						CurrentThreadContext.getCurrentOrgCd());

				// 付款状态(数据字典)列表
				List<KeyValueVO> payStateList = sysDictionaryApiService.getKvList(
						FncCapPayeeInfoBigConstant.FNC_PAY_STATE, CurrentThreadContext.getCurrentSysCd(),
						CurrentThreadContext.getCurrentOrgCd());
				
				for (FncCapPayeeInfoBigDTO fncCapPayeeInfoBigDTO : resultList) {

					// 付款类型(数据字典)
					if (CollectionUtils.isNotEmpty(payTypeList)) {
						if (StringUtils.isNotBlank(fncCapPayeeInfoBigDTO.getPayType())) {
							for (KeyValueVO keyValueVO : payTypeList) {
								if (fncCapPayeeInfoBigDTO.getPayType().equals(keyValueVO.getKey())) {
									fncCapPayeeInfoBigDTO.setPayTypeNm(keyValueVO.getValue());
									break;
								}
							}
						}
					}

					// 付款状态(数据字典)
					if (CollectionUtils.isNotEmpty(payStateList)) {
						if (StringUtils.isNotBlank(fncCapPayeeInfoBigDTO.getPayState())) {
							for (KeyValueVO keyValueVO : payStateList) {
								if (fncCapPayeeInfoBigDTO.getPayState().equals(keyValueVO.getKey())) {
									fncCapPayeeInfoBigDTO.setPayStateNm(keyValueVO.getValue());
									break;
								}
							}
						}
					}

					//获取流程信息
					if (StringUtils.isNotBlank(fncCapPayeeInfoBigDTO.getpNo())) {
						FncCapPayeeInfoBigQueryCondition condition = new FncCapPayeeInfoBigQueryCondition();
						condition.setpNo(fncCapPayeeInfoBigDTO.getpNo());
						condition.setId(fncCapPayeeInfoBigDTO.getId());
						condition.setIsDel(FncCapPayeeInfoBigConstant.IS_DEL_NO);
						
						List<Map<String, Object>> flowList = fncCapPayeeInfoBigApiService.getFlow(condition);
						if (CollectionUtils.isNotEmpty(flowList)) {
							Map<String, Object> flowMap = flowList.get(0);
							
							fncCapPayeeInfoBigDTO.setpInstId((String)flowMap.get("P_INST_ID"));
							fncCapPayeeInfoBigDTO.setAudStsCd((String)flowMap.get("AUD_STS_CD"));
							fncCapPayeeInfoBigDTO.setBusTyp((String)flowMap.get("BUS_TYP"));
						}
					}
				}
			}
		}

		return pager;
	}

	@Override
	public List<FncCapPayeeInfoBigVO> searchList(FncCapPayeeInfoBigQueryCondition condition) {
		return FncCapPayeeInfoBigVOTransform.toVOList(this.fncCapPayeeInfoBigApiService.searchList(condition));
	}

	@Override
	public DataResultDTO addFlowStart(FlowStartParamsDTO flowStartParamsDTO) throws BaseException {
		DataResultDTO result = new DataResultDTO(BaseExceptionConstant.BASE_EXCEPTION_CODE_200,
				SysLogConstant.LOG_CMM_OPERATE_SUCC);
		if (StringUtils.isEmpty(flowStartParamsDTO.getCrtUsrId())
				|| StringUtils.isEmpty(flowStartParamsDTO.getBusinessKey())) {
			BaseLogUtils.info(logger, "addFlowStart", "用户ID和业务数据主键必须要存在!", CurrentThreadContext.getCurrentUserName());
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "用户ID和业务数据主键必须要存在!");
		}
		BaseLogUtils.info(logger, "addFlowStart", "===发起流程Start===参数:" + JSON.toJSONString(flowStartParamsDTO));
        result = this.flowApiService.noTransFlowStart(flowStartParamsDTO);
        BaseLogUtils.info(logger, "addFlowStart", "===发起流程End===结果:" + JSON.toJSONString(result));
        return  result;
		
	}
	/**
	 * 出纳付款发送拜特网银接口
	 * 
	 * @author gengchunlan
	 * @date 20200222
	 */
	@Override
	public DataResultDTO sendPay(FncCapPayeeInfoBigVO fncCapPayeeInfoBig) {
		
		DataResultDTO  resultDTO = new DataResultDTO(BaseConstant.IS_YESNO_NO, SysLogConstant.LOG_CMM_DELETE_FAIL);
		//1 生成sign签名
		String sign = "";// 请求参数签名，采用SHA256签名，RSA加密，Base64编码。
		String privateKey1 = PropertiesCacheUtils.getProperty(privateKey);
		String publicKey1 = PropertiesCacheUtils.getProperty("fncbigpay.fncbigpay.properties.paybig.publicKey");
		String reqId = UUID.randomUUID().toString().replace("-", "");// reqId 流水号 Y
		String finCode1 ="bfs";// String 30 对接系统代码，用于标识唯一的对接系统 Y
		String orgCode1 =PropertiesCacheUtils.getProperty(orgCode); // 合作方代码，用于标识唯一的合作方
		String seCode = PropertiesCacheUtils.getProperty(seCode1); // String 服务代码，请参考具体接口描述 Y
		String version =PropertiesCacheUtils.getProperty(version1); // 版本号，请参考具体接口描述
		String signKeyIdx1 = PropertiesCacheUtils.getProperty(signKeyIdx);// String 签名密钥索引
		PayeeBigUtil bigUtil = new PayeeBigUtil();
		JSONObject reqBody = bigUtil.payBigParam(fncCapPayeeInfoBig);// JSON 业务参数，所有接口的请求业务参数都必须放入该字段
		Long curdate = System.currentTimeMillis();
		String timestamp = curdate.toString();// String请求发送时间戳，单位为毫秒
		String signStr = "reqId=" + reqId + "&orgCode="+orgCode1+"&finCode="+finCode1+"&seCode="+seCode
				+ "&version="+version+"&signKeyIdx="+signKeyIdx1+"&reqBody="+reqBody+"&timestamp="
				+ timestamp;
		BaseLogUtils.info(logger, "payBigParam", "发送大额付款发送网银报文===signStr" + signStr);
		try {
			sign = bigUtil.rsaSign(signStr, privateKey1, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		}
		BaseLogUtils.info(logger, "payBigParam", "发送大额付款发送网银报文===sign" + sign);
		// 2 封装请求报文
		JSONObject params = new JSONObject();
		params.put("reqId", reqId);
		params.put("orgCode", orgCode1);
		params.put("finCode", finCode1);
		params.put("seCode", seCode);
		params.put("version", version);
		params.put("signKeyIdx", signKeyIdx1);
		params.put("sign", sign);
		params.put("reqBody", reqBody);
		params.put("timestamp", timestamp);
		BaseLogUtils.info(logger, "payBigParam", "返回大额付款发送网银报文===jsonInfo" + params);
		//3 发送请求
		String response = "";
		try {
			 synchronized (this) {
				response = PayeeBigUtil.PostHttpRequest(params);
			}
			BaseLogUtils.info(logger, "payBigParam", "返回大额付款网银报文===jsonResponse" + response);
		} catch (Exception e) {
			e.printStackTrace();
		}
		//4 解析返回数据
		JSONObject retn = JSONObject.parseObject(response);
		int respStatus=0;
		String respCode="";
		String respDesc="";
		String rereqId ="";
		String resign ="";	
		if(retn.containsKey("respStatus")) {//响应状态，0失败，1成功 
			respStatus=retn.getIntValue("respStatus");
		}
		if(retn.containsKey("respCode")) {//响应码
			respCode=retn.get("respCode").toString();
		}
		if(retn.containsKey("respDesc")) {//响应信息
			respDesc=retn.get("respDesc").toString();
		}
		if(retn.containsKey("reqId")) {//请求报文中的流水号中的值
			rereqId=retn.get("reqId").toString();
		}
		if(retn.containsKey("sign")) {//响应报文中的签名值
			resign=retn.get("sign").toString();
		}
		FncCapPayeeInfoBigVO fncCapPayeeInfoBigVO = new FncCapPayeeInfoBigVO();
		fncCapPayeeInfoBigVO.setId(fncCapPayeeInfoBig.getId());
		fncCapPayeeInfoBigVO.setMdfUsrId(CurrentThreadContext.getCurrentUserId());
		fncCapPayeeInfoBigVO.setMdfTm(new Date());
		// 5  校验签名 respStatus+respCode+respDesc+reqId+respBody
		String data="respStatus="+respStatus+"&respCode="+respCode+"&respDesc="+respDesc+"&reqId="+rereqId;
		BaseLogUtils.info(logger, "payBigParam", "返回大额付款网银报文验证签名===data" + data);
		try {
			boolean result = PayeeBigUtil.rsaCheckContent(data, resign, publicKey1, "UTF-8");
			if(result) {
				fncCapPayeeInfoBigVO.setSign("1");	//响应签名 校验成功
			}else {
				fncCapPayeeInfoBigVO.setSign("2");//响应签名 校验失败
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		fncCapPayeeInfoBigVO.setSendSt("sendFailure");
		if("0000".equals(respCode)) {
			resultDTO.setSuccess(BaseConstant.IS_YESNO_YES);
			fncCapPayeeInfoBigVO.setSendSt("sendSuccess");
		}
		fncCapPayeeInfoBigVO.setMsg(respDesc);
		resultDTO.setCode(respCode);//响应码
		resultDTO.setInfo(respDesc);//响应信息
		resultDTO.setData(response);//返回信息
		fncCapPayeeInfoBigApiService.updatePayerAcc(FncCapPayeeInfoBigVOTransform.toDTO(fncCapPayeeInfoBigVO));
		return resultDTO;
	}
	@Override
	public boolean updatePayerAcc(FncCapPayeeInfoBigVO bigVo) {
		return fncCapPayeeInfoBigApiService.updatePayerAcc(FncCapPayeeInfoBigVOTransform.toDTO(bigVo));
	}
	@Override
	public FncCapPayeeInfoBigVO callPaymentQuery(FncCapPayeeInfoBigVO bigVo) {
		return FncCapPayeeInfoBigVOTransform.toVO(fncCapPayeeInfoBigApiService.callPaymentQuery(FncCapPayeeInfoBigVOTransform.toDTO(bigVo)));
	}
}
